\documentclass[12pt,titlepage]{article}
\usepackage[spanish]{babel}
\usepackage[utf8]{inputenc}
\usepackage{amssymb}
\usepackage{graphicx} % para insertar imagenes

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% macros para pseudocodigo %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\func}[2]{\texttt{#1}(#2)\\}
\newcommand{\tab}{\hspace*{2em}}
\newcommand{\FOR}{\textbf{for }}
\newcommand{\TO}{\textbf{ to }}
\newcommand{\IF}{\textbf{if }}
\newcommand{\INC}{\textbf{inc }}
\newcommand{\WHILE}{\textbf{while }}
\newcommand{\THEN}{\textbf{then }}
\newcommand{\ELSE}{\textbf{else }}
\newcommand{\RET}{\textbf{return }}
\newcommand{\MOD}{\textbf{ \% }}
\newcommand{\OR}{\textbf{ or }}
\newcommand{\VSP}{\vspace*{3em}}
\newcommand{\Pa}{\vspace{5mm}}
\newcommand{\gramed}[1]{\noindent\includegraphics[scale=0.5]{#1}\\}
\newcommand{\gra}[1]{\noindent\includegraphics[scale=0.30]{#1}}
\newcommand{\inst}[1]{\texttt{\textbf{#1}}}
\newcommand{\descrip}[1]{\textit{(#1)}}
\newenvironment{pseudo}{\vspace*{2em}}

% ** para itemizar con abc **

\newcounter{ale}

\newcommand{\abc}{\item[\alph{ale})]\stepcounter{ale}}

\newenvironment{liste}{\begin{itemize}}{\end{itemize}}
\newcommand{\aliste}{\begin{liste} \setcounter{ale}{1}}
\newcommand{\zliste}{\end{liste}}

\newenvironment{abcliste}{\aliste}{\zliste}

% ****************************

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\dirmail}[1]{\normalsize{\texttt{#1}}}

\title{{\sc\normalsize Organización del computador II}\\{\bf Trabajo Práctico Nº3}}
\author{\begin{tabular}{lcr}Thomas Fischer & 489/08 & \dirmail{tfischer@dc.uba.ar}\\Kevin Allekotte & 490/08 & \dirmail{kevinalle@gmail.com} \end{tabular}}
\date{\VSP \normalsize{Noviembre 2009}}

\begin{document}

	\begin{titlepage}
		\maketitle
	\end{titlepage}

	\tableofcontents
	\newpage

	\begin{section}{Introducción}
		Este trabajo tiene como objetivo la constucción de un sistema operativo minimal que corra dos tareas concurrentemente.
		Para ello de deben resolver sucesivos ejercicios que inicializen la computadora para poder ejecutar las tareas.
		Éstos incluyen por ejemplo: cargar las tablas de descriptores (GDT, IDT, etc), pasar a modo protegido, habilitar la paginacion, remapear la memoria, cargar las tareas, entre otros.
		
		Para realizar el trabajo se usa el programa \texttt{bochs}, que permite simular una computadora IBM-PC y debbugear.
		Usamos la imagen de un diskette para bootear, que ya tiene precargado el bootloader.
		El mismo busca en el diskette el archivo \texttt{kernel.bin}, lo copia a memoria y comienza a ejecutarlo.
		Nuestro objetivo es crear el \texttt{kernel.bin} de tal forma que ejecute las dos tareas en 'simultaneo' con el mapeo de memoria correspondiente.
	\end{section}

	\begin{section}{Desarrollo}

		\begin{subsection}{Ejercicio 1}

			\begin{abcliste}

				\abc La tabla de descriptores globales del sistema, es una tabla de 128 descriptores definida en el archivo \texttt{gdt.c}.
				Estos descriptores describen los segmentos que vamos a querer utilizar en modo protegido
				En este ejercicio definimos explícitamente las 4 primeras entradas con los descriptores \texttt{nil}, código de kernel, datos de kernel y memoria de video respectivamente,
				que son los unicos que nos interesa utilizar por ahora. Los descriptores trabajan en nivel 0 y en modo de 32bit.

				\abc También queda definido en el mismo archivo el descriptor de la tabla que es cargado al registro GDTR del sistema por medio de la instruccion \texttt{lgdt}.
				Así el sistema ya tiene conocimiento de los descriptores que designamos para el funcionamiento del mismo en modo protegido.

				Luego pasamos a habilitar el modo protegido en la computadora, seteando el bit 1 (también conocido como PE) del registro de control \texttt{CR0} en 1.

				Ya en modo protegido saltamos a la rutina \texttt{modo\_protegido}, cambiando el segmento de código del sistema a un índice correspondiente del descriptor del segmento de código de la GDT,
				ya que los segmentos de codigo y de datos en modo protegido trabajan a través de los descriptores.
				El sistema siempre nos deja hacer un ultimo salto antes de cambiar el segmento al de modo protegido con el segmento de codigo de modo real como referencia. En nuestro es lo mismo pero podría pasar que no.
				Esto lo logramos mediante un far jump, que es la única manera de modificar el registro de segmento de código en modo protegido.

				De paso esto nos limpia el pipeline de ejecución del procesador que tal vez contenía instrucciones a ejecutarse en modo real.

				\abc Ya en modo protegido, procedemos a limpiar la pantalla y pintar un marco en los bordes de la misma escribiendo a la memoria de video utilizando el descriptor de video definido en la GDT (entrada 4).

			\end{abcliste}

		\end{subsection}

		\begin{subsection}{Ejercicio 2}

			\begin{abcliste}

				\abc En el archivo \texttt{paging.asm} definimos dos directorios de paginas distintos. Uno para la tarea pintor y el otro para la tarea traductor y el kernel en general.
				Los directorios tienen 1024 entradas donde cada una es un descriptor que hace referencia a una tabla de paginación.

				Definimos todos estos descriptores como nulos y como no presentes, ya que solo vamos a usar el primero, porque no necesitamos direccionar mucha memoria.

				Las tablas las llenamos de manera que correspondan al mapeo de memoria indicado por el enunciado de la materia.

				Luego en el codigo del kernel tomamos las direcciones de las tablas que usamos, y las referenciamos en la primera entrada de cada directorio de paginas correspondiente,
				seteando ademas al descriptor de la tabla como presente.
				Ademas cargamos como directorio de paginas inicial el del kernel, poniendo su dirección en el registro de control \texttt{CR3} del sistema (que guarda la dirección del actual directorio de páginas).

				Luego ya estamos listos para trabajar con memoria paginada, por lo que la habilitamos seteando el bit mas significativo, el 31 (también conocido como PG) del registro de control \texttt{CR0} en 1.

				\abc Ya con la memoria paginada, escribimos el nombre del grupo en la pantalla a partir de la coordenada (2,2) usando el nuevo mapa de memoria, en el cual sobre la dirección de la memoria de video hay configurado un identity mapping, entonces basta con escribir directamente a la misma (\texttt{0xb8000}).

			\end{abcliste}

		\end{subsection}

		\begin{subsection}{Ejercicio 3}

			\begin{abcliste}

				\abc La tabla de descriptores de interrupciones es una tabla de 256 entradas, donde cada una está asociada a una interrupcion y el descriptor tiene la dirección de la rutina que la atiende..
				La tabla es llenada mediante una llamada a la funcion \texttt{idtFill()} definida en \texttt{idt.c}.

				Los descriptores inicialmente contienen como asociada una rutina por defecto, que fue definida para avisar cuando se llama alguna interrupcion a la cual no le asignamos explicitamente una rutina que la maneje.
				Luego asociamos las pocas interrupciones que nos interesan con las direcciones de sus respectivas rutinas.
				Estas son la del reloj, que vamos a usar para hacer un cambio de tareas, y algunas de las excepciones de la cpu, asi sabemos donde metimos la pata cuando se produce una de ellas.

				Ademas hicimos un pequeño handler de la interrupcion del teclado para que el programa no explote si un usuario presiona una tecla.

				Luego de llenar la tabla, debemos remapear las interrupciones del PIC a partir de la direccion 0x32, las cuales están designadas para el uso del programador.
				Las interrupciones anteriores estan reservadas por intel para las interrupciones del CPU, pero IBM por defecto las pisa con su propio vector. Por esto es que hay que reubicarlas.

				Luego de esto cargamos el descriptor de la IDT mediante la instruccion lidt, asi el sistema tiene conocimiento de la misma.

				Por supuesto todo esto se hace con las interrupciones deshabilitadas desde el principio, ya que las rutinas de las mismas no estan definidas.

				\abc La rutina del next\_clock, que controla el cambio de tareas, es directamente la rutina de atencion de la interrupcion del reloj (0x32);

			\end{abcliste}

		\end{subsection}
		
		
		\newpage

		\begin{subsection}{Ejercicio 4}

			\begin{abcliste}

				\abc Generamos 3 tablas de TSS.
				La primera es la nula, que esta cargada inicialmente, ya que cuando saltamos a la primer tarea tiene que haber una TSS válida donde el sistema pueda volcar los datos actuales.
				Las otas dos TSS son las de las tareas pintor y traductor. Las pilas de las tareas estan definidas en los espacios de memoria designados en el enunciado, pero empiezan en la posicion de memoria mas alta, ya que crecen hacia abajo.
				Los segmentos son los mismos para ambas, y el registro \texttt{CR3} es la dirección del directorio de páginas que definimos para cada tarea.

				\abc Pusimos 3 descriptores de TSS en la GDT en referencia a las TSS que creamos.

				\abc Para la rutina que realiza el cambio de tareas, primero definimos una variable global current\_task que guarda el numero de la tarea actual, y esta inicializada en 1.
				Luego, en la rutina de atencion de la interrupcion del reloj, si esta variable esta en 1, la seteamos en 2 y hacemos un cambio a la tarea dos,
				y en caso contrario (si esta en 2) le asignamos un 1 y cambiamos a la tarea 1.

				Para realizar los cambios de las tareas, simplemente hacemos un jump far al descriptor de la tss correspondiente a la tarea en la GDT.
				Luego el propio CPU se encarga de guardar el estado de la tarea que para, y de cargar el estado de la tarea que arranca.

				Esto es necesario para que cada vez que vuelva a arrancar una tarea, siga desde donde se corto la última vez, y asi se pueda ejecutar en su totalidad como si no la hubiesen interrumpido.

			\end{abcliste}

		\end{subsection}

	\end{section}

\newpage
	%\begin{section}{Discusión}
		
	%\end{section}
	

	\begin{section}{Resultados y Conclusiones}
		\noindent\includegraphics[width=120mm]{starwars.jpg}
		\\
		
		Luego de ejecutar las tareas se observa en la salida de video un mensaje bien nerd..
		
		\bigskip
		Grabamos la imagen en un diskette y booteamos una PC (con disquetera) con ese disco. La PC inicia correctamente y muestra el mensaje y los relojes (significa que conmutamos bien las tareas).
	\end{section}
	
	\newpage

	%%\begin{section}{Conclusiones}

		

	%%\end{section}

	\newpage

	%%\begin{section}{Manual}
	%%	man
	%%\end{section}

	\newpage

	\begin{section}{Archios incluídos}

		\begin{itemize}

			\item archivosTP3

				\begin{itemize}

					\item Makefile
					\item kernel.asm
					\item  a20.asm
					\item gdt.h
					\item gdt.c
					\item idt.h
					\item idt.c
					\item isr.h
					\item isr.asm
					\item tss.h
					\item tss.c
					\item paging.asm
					\item macrosmodoprotegido.mac
					\item macrosmodoreal.mac
					\item pintor.tsk
					\item traductor.tsk
					\item kernel.bin
					\item diskette.img
					\item bochsrc

				\end{itemize}

			\item enunciado

				\begin{itemize}

					\item EnunciadoTP3.pdf

				\end{itemize}

			\item informe

				\begin{itemize}

					\item informeTP3.pdf

				\end{itemize}

		\end{itemize}

	\end{section}

\end{document}
